/*
 * Copyright 2008 The Brui Team
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at 
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */
 
 package com.googlecode.brui.editors;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * <p>Creates an editor for integers based on get/set methods and an object. Action
 * listeners are automatically registered in the constructor so essentially this is
 * just a JSpinner component :).</p>
 * 
 * @author <a href="http://daemonsadvocate.blogspot.com/">The Daemons Advocate</a>
 * @version 1.0: 9/07/2008, 2:09:37 PM
 */
public class IntegerEditor extends JSpinner {
	private static final long serialVersionUID = -3809240731368672562L;
	private static final Object[] GETTER_ARGS = new Object[0];
	
	/**
	 * @param getter Standard javabeans getter method.
	 * @param setter Standard javabeans setter method.
	 * @param instance Object instance to execute get/set method on.
	 * @throws IllegalArgumentException
	 */
	public IntegerEditor(final Method getter, final Method setter, final Object instance)
			throws IllegalArgumentException {
		super(new SpinnerNumberModel());
		
		// 0. Preconditions
		if(instance==null || getter==null || setter==null)
			throw new NullPointerException("Must specify all fields in Component Integer Constructor");
		
		try {
			// 1. Setup initial settings for this component. (display value)
			Integer value = (Integer)getter.invoke(instance, GETTER_ARGS);
			this.setValue(value);
			
			// 2. Add a change listener so that changes are registered by the bean.
			this.addChangeListener(
				new ChangeListener() {
					public void stateChanged(ChangeEvent event) {
						// Pull the source and get at the new value
						IntegerEditor that = (IntegerEditor)event.getSource();
						Object[] args = { that.getValue() };
						try {
							setter.invoke(instance, args);
						} // ...fail silently
						catch (IllegalArgumentException ex) { ex.printStackTrace(); }
						catch (IllegalAccessException ex) { ex.printStackTrace(); }
						catch (InvocationTargetException ex) { ex.printStackTrace(); }
					}
				}
			);
			
		} // ...fail silently
		catch (IllegalAccessException ex) { ex.printStackTrace(); }
		catch (InvocationTargetException ex) { ex.printStackTrace(); }
	}
}
